<template>
  <div class="flex flex-col h-screen bg-gray-100 overflow-hidden">
    <!-- 顶部工具栏 -->
    <header class="bg-white border-b border-gray-200 py-2 px-4 flex items-center justify-between">
      <div class="flex items-center space-x-4">
        <h1 class="text-lg font-bold text-dark flex items-center">
          <i class="fa fa-pencil-square-o text-primary mr-2"></i>
          增强型可视化编辑器
        </h1>
        
        <div class="flex items-center space-x-2">
          <button @click="importHtml" class="px-3 py-1.5 border border-primary text-primary rounded text-sm hover:bg-primary/5 transition-colors">
            <i class="fa fa-upload mr-1"></i> 导入HTML
          </button>
          <button @click="saveContent" class="px-3 py-1.5 bg-primary text-white rounded text-sm hover:bg-primary/90 transition-colors">
            <i class="fa fa-save mr-1"></i> 保存
          </button>
          <button @click="exportHtml" class="px-3 py-1.5 border border-primary text-primary rounded text-sm hover:bg-primary/5 transition-colors">
            <i class="fa fa-download mr-1"></i> 导出HTML
          </button>
        </div>
      </div>
      
      <div class="flex items-center space-x-1">
        <button class="toolbar-btn" title="撤销" @click="undo">
          <i class="fa fa-undo"></i>
        </button>
        <button class="toolbar-btn" title="重做" @click="redo">
          <i class="fa fa-repeat"></i>
        </button>
        <div class="h-5 border-r border-gray-300 mx-1"></div>
        <button class="toolbar-btn" title="变量管理" @click="showVariables = !showVariables">
          <i class="fa fa-variable"></i>
          <span class="ml-1 text-xs hidden sm:inline">变量</span>
        </button>
        <div class="h-5 border-r border-gray-300 mx-1"></div>
        <button class="toolbar-btn" title="预览模式" @click="toggleEditMode">
          <i class="fa" :class="isEditMode ? 'fa-eye' : 'fa-pencil'"></i>
          <span class="ml-1 text-xs hidden sm:inline">{{ isEditMode ? '预览' : '编辑' }}</span>
        </button>
      </div>
    </header>
    
    <!-- 编辑模式工具栏 -->
    <div v-if="isEditMode" class="bg-white border-b border-gray-200 px-4 py-2 flex flex-wrap items-center gap-3">
      <div class="flex items-center space-x-2">
        <button class="toolbar-btn" title="添加标题" @click="addElement('heading')">
          <i class="fa fa-header"></i>
        </button>
        <button class="toolbar-btn" title="添加段落" @click="addElement('paragraph')">
          <i class="fa fa-paragraph"></i>
        </button>
        <button class="toolbar-btn" title="添加图片" @click="addElement('image')">
          <i class="fa fa-picture-o"></i>
        </button>
        <button class="toolbar-btn" title="添加视频" @click="addElement('video')">
          <i class="fa fa-film"></i>
        </button>
        <button class="toolbar-btn" title="添加音频" @click="addElement('audio')">
          <i class="fa fa-music"></i>
        </button>
        <button class="toolbar-btn" title="添加按钮" @click="addElement('button')">
          <i class="fa fa-square-o"></i>
        </button>
        <button class="toolbar-btn" title="添加分隔线" @click="addElement('divider')">
          <i class="fa fa-minus"></i>
        </button>
        <button class="toolbar-btn" title="添加原始HTML块" @click="addElement('rawHtml')">
          <i class="fa fa-code"></i>
        </button>
      </div>
      
      <!-- 变量插入工具栏 -->
      <div v-if="variables.length > 0" class="flex items-center space-x-2 ml-4">
        <span class="text-xs text-gray-500">插入变量:</span>
        <select 
          class="text-sm border border-gray-300 rounded px-2 py-1"
          @change="insertVariable($event.target.value)"
          @click.stop
        >
          <option value="">选择变量...</option>
          <option v-for="varItem in variables" :value="varItem.name" :key="varItem.name">
            {{ varItem.name }} ({{ varItem.value.substring(0, 20) }}{{ varItem.value.length > 20 ? '...' : '' }})
          </option>
        </select>
      </div>
      
      <div v-if="selectedElement" class="flex items-center space-x-2 ml-auto">
        <button class="toolbar-btn" title="上移" @click="moveElement('up')">
          <i class="fa fa-arrow-up"></i>
        </button>
        <button class="toolbar-btn" title="下移" @click="moveElement('down')">
          <i class="fa fa-arrow-down"></i>
        </button>
        <div class="h-5 border-r border-gray-300 mx-1"></div>
        <button class="toolbar-btn text-red-500 hover:bg-red-50" title="删除" @click="deleteElement">
          <i class="fa fa-trash"></i>
        </button>
      </div>
    </div>
    
    <!-- 主编辑区域 -->
    <main class="flex-1 overflow-auto bg-gray-50 p-4 sm:p-6 flex">
      <div class="max-w-4xl mx-auto bg-white rounded-lg shadow-md overflow-hidden flex-1">
        <!-- 编辑内容区域 -->
        <div 
          class="p-6 min-h-[600px]" 
          @click="deselectElement"
        >
          <div 
            v-for="(element, index) in contentElements" 
            :key="element.id"
            :class="{ 'ring-2 ring-primary ring-offset-2': selectedElement?.id === element.id }"
            @click.stop="selectElement(element, index)"
            class="mb-6 transition-all"
          >
            <!-- 标题元素 -->
            <div v-if="element.type === 'heading'">
              <h2 
                v-if="element.level === 2" 
                :contenteditable="isEditMode && selectedElement?.id === element.id"
                @input="updateElementContent(element.id, $event.target.innerHTML)"
                :style="element.style"
                v-html="replaceVariables(element.content)"
              ></h2>
              <h3 
                v-if="element.level === 3" 
                :contenteditable="isEditMode && selectedElement?.id === element.id"
                @input="updateElementContent(element.id, $event.target.innerHTML)"
                :style="element.style"
                v-html="replaceVariables(element.content)"
              ></h3>
            </div>
            
            <!-- 段落元素 -->
            <p 
              v-if="element.type === 'paragraph'"
              :contenteditable="isEditMode && selectedElement?.id === element.id"
              @input="updateElementContent(element.id, $event.target.innerHTML)"
              :style="element.style"
              v-html="replaceVariables(element.content)"
            ></p>
            
            <!-- 图片元素 -->
            <div v-if="element.type === 'image'" class="relative">
              <img 
                :src="replaceVariables(element.src)" 
                :alt="replaceVariables(element.alt || '图片')" 
                :style="element.style"
              >
              <button 
                v-if="isEditMode && selectedElement?.id === element.id"
                class="absolute top-2 right-2 bg-black/50 text-white p-2 rounded-full hover:bg-black/70 transition-colors"
                @click.stop="openMediaEditDialog('image', element.id)"
              >
                <i class="fa fa-pencil"></i>
              </button>
            </div>
            
            <!-- 视频元素 -->
            <div v-if="element.type === 'video'" class="relative">
              <video 
                :src="replaceVariables(element.src)" 
                :poster="replaceVariables(element.poster || '')"
                controls
                :style="element.style"
              >
                您的浏览器不支持视频播放
              </video>
              <button 
                v-if="isEditMode && selectedElement?.id === element.id"
                class="absolute top-2 right-2 bg-black/50 text-white p-2 rounded-full hover:bg-black/70 transition-colors"
                @click.stop="openMediaEditDialog('video', element.id)"
              >
                <i class="fa fa-pencil"></i>
              </button>
            </div>
            
            <!-- 音频元素 -->
            <div v-if="element.type === 'audio'" class="relative">
              <audio 
                :src="replaceVariables(element.src)" 
                controls
                :style="element.style"
              >
                您的浏览器不支持音频播放
              </audio>
              <button 
                v-if="isEditMode && selectedElement?.id === element.id"
                class="absolute top-2 right-2 bg-black/50 text-white p-2 rounded-full hover:bg-black/70 transition-colors"
                @click.stop="openMediaEditDialog('audio', element.id)"
              >
                <i class="fa fa-pencil"></i>
              </button>
            </div>
            
            <!-- 按钮元素 -->
            <button 
              v-if="element.type === 'button'"
              :contenteditable="isEditMode && selectedElement?.id === element.id"
              @input="updateElementContent(element.id, $event.target.innerHTML)"
              :style="element.style"
              v-html="replaceVariables(element.content)"
              @click.stop="handleButtonClick"
            ></button>
            
            <!-- 分隔线元素 -->
            <hr v-if="element.type === 'divider'" :style="element.style">
            
            <!-- 原始HTML块 -->
            <div v-if="element.type === 'rawHtml'">
              <div 
                v-if="!isEditMode || !selectedElement?.id === element.id"
                :style="element.style"
                v-html="replaceVariables(element.content)"
              ></div>
              
              <div v-else>
                <div class="bg-gray-50 p-2 border border-gray-200 mb-2 text-xs text-gray-500">
                  编辑原始HTML (会保留所有标签和样式)
                </div>
                <textarea 
                  v-model="element.content"
                  @input="updateElementContent(element.id, element.content)"
                  class="w-full p-2 border border-gray-300 rounded text-sm min-h-[150px] font-mono text-xs"
                ></textarea>
              </div>
            </div>
          </div>
          
          <!-- 空状态提示 -->
          <div v-if="contentElements.length === 0 && isEditMode" class="text-center py-12 text-gray-500">
            <i class="fa fa-file-text-o text-4xl mb-3"></i>
            <p>点击上方工具栏添加内容元素，或导入HTML文件开始编辑</p>
          </div>
        </div>
      </div>
      
      <!-- 变量管理面板 -->
      <div 
        v-if="showVariables" 
        class="w-full md:w-80 bg-white border-t md:border-t-0 md:border-l border-gray-200 p-4 overflow-y-auto transition-all duration-300 ml-4"
      >
        <h3 class="font-medium text-gray-800 mb-3 flex justify-between items-center">
          <span>变量管理</span>
          <button @click="addNewVariable" class="text-primary hover:text-primary/80">
            <i class="fa fa-plus"></i> 添加变量
          </button>
        </h3>
        
        <div class="space-y-3">
          <div v-if="variables.length === 0" class="text-center py-6 text-gray-500 text-sm">
            <i class="fa fa-info-circle mb-2"></i>
            <p>暂无变量，请点击"添加变量"按钮创建</p>
          </div>
          
          <div v-for="(variable, index) in variables" :key="variable.name" class="p-3 border border-gray-200 rounded-lg">
            <div class="flex justify-between items-start mb-2">
              <div class="flex-1">
                <label class="block text-xs text-gray-500 mb-1">变量名</label>
                <div class="flex">
                  <span class="inline-flex items-center px-2 py-1 bg-gray-100 text-gray-500 text-xs rounded-l">${</span>
                  <input 
                    type="text" 
                    v-model="variable.name"
                    @change="validateVariableName(index)"
                    class="flex-1 p-1 border-y border-gray-300 text-sm focus:outline-none"
                    placeholder="variable_name"
                  >
                  <span class="inline-flex items-center px-2 py-1 bg-gray-100 text-gray-500 text-xs rounded-r">}</span>
                </div>
              </div>
              <button 
                class="text-red-400 hover:text-red-600 ml-2"
                @click="removeVariable(index)"
              >
                <i class="fa fa-times"></i>
              </button>
            </div>
            
            <div>
              <label class="block text-xs text-gray-500 mb-1">变量值</label>
              <textarea 
                v-model="variable.value"
                @input="updateVariableValue(index)"
                class="w-full p-2 border border-gray-300 rounded text-sm min-h-[80px]"
                placeholder="变量替换的值..."
              ></textarea>
            </div>
            
            <div class="mt-2 text-xs text-gray-400 flex items-center">
              <i class="fa fa-info-circle mr-1"></i>
              <span>使用: 在内容中输入 ${变量名} 或通过上方下拉菜单插入</span>
            </div>
          </div>
        </div>
      </div>
      
      <!-- 元素属性编辑面板 -->
      <div 
        v-if="isEditMode && selectedElement && !showVariables" 
        class="w-full md:w-80 bg-white border-t md:border-t-0 md:border-l border-gray-200 p-4 overflow-y-auto transition-all duration-300 ml-4"
      >
        <h3 class="font-medium text-gray-800 mb-3 flex justify-between items-center">
          <span>元素属性</span>
          <button @click="deselectElement" class="text-gray-500 hover:text-gray-700">
            <i class="fa fa-times"></i>
          </button>
        </h3>
        
        <!-- 原始HTML块属性 -->
        <div v-if="selectedElement.type === 'rawHtml'">
          <div class="mb-3">
            <label class="block text-sm text-gray-600 mb-1">HTML内容</label>
            <textarea 
              v-model="selectedElement.content"
              @input="updateElementProperties"
              class="w-full p-2 border border-gray-300 rounded text-sm min-h-[200px] font-mono text-xs"
            ></textarea>
          </div>
          <div class="text-xs text-gray-500 p-2 bg-gray-50 rounded">
            <p><i class="fa fa-info-circle mr-1"></i> 原始HTML块会保留所有标签和样式，适合导入复杂内容</p>
          </div>
        </div>
        
        <div v-if="selectedElement.type === 'heading'">
          <div class="mb-3">
            <label class="block text-sm text-gray-600 mb-1">标题级别</label>
            <select 
              v-model="selectedElement.level"
              @change="updateElementProperties"
              class="w-full p-2 border border-gray-300 rounded text-sm"
            >
              <option value="2">H2</option>
              <option value="3">H3</option>
            </select>
          </div>
          <div class="mb-3">
            <label class="block text-sm text-gray-600 mb-1">标题内容</label>
            <textarea 
              v-model="selectedElement.content"
              @input="updateElementProperties"
              class="w-full p-2 border border-gray-300 rounded text-sm min-h-[80px]"
            ></textarea>
          </div>
          <div class="mb-3">
            <label class="block text-sm text-gray-600 mb-1">自定义样式 (CSS)</label>
            <input 
              type="text" 
              v-model="selectedElement.style.cssText"
              @input="updateElementStyleFromCssText"
              class="w-full p-2 border border-gray-300 rounded text-sm"
              placeholder="color: red; font-size: 20px;"
            >
          </div>
        </div>
        
        <div v-if="selectedElement.type === 'paragraph'">
          <div class="mb-3">
            <label class="block text-sm text-gray-600 mb-1">段落内容</label>
            <textarea 
              v-model="selectedElement.content"
              @input="updateElementProperties"
              class="w-full p-2 border border-gray-300 rounded text-sm min-h-[100px]"
            ></textarea>
          </div>
          <div class="mb-3">
            <label class="block text-sm text-gray-600 mb-1">自定义样式 (CSS)</label>
            <input 
              type="text" 
              v-model="selectedElement.style.cssText"
              @input="updateElementStyleFromCssText"
              class="w-full p-2 border border-gray-300 rounded text-sm"
              placeholder="color: blue; text-align: center;"
            >
          </div>
        </div>
        
        <div v-if="['image', 'video', 'audio'].includes(selectedElement.type)">
          <div class="mb-3">
            <label class="block text-sm text-gray-600 mb-1">{{ selectedElement.type === 'image' ? '图片' : selectedElement.type === 'video' ? '视频' : '音频' }}地址 (URL)</label>
            <input 
              type="text" 
              v-model="selectedElement.src"
              @input="updateElementProperties"
              class="w-full p-2 border border-gray-300 rounded text-sm"
              placeholder="https://example.com/media.mp4"
            >
          </div>
          
          <div v-if="selectedElement.type === 'image' || selectedElement.type === 'video'" class="mb-3">
            <label class="block text-sm text-gray-600 mb-1">
              {{ selectedElement.type === 'image' ? '图片描述' : '视频封面图' }}
            </label>
            <input 
              type="text" 
              v-model="selectedElement.alt"
              @input="updateElementProperties"
              class="w-full p-2 border border-gray-300 rounded text-sm"
              placeholder="{{ selectedElement.type === 'image' ? '图片描述' : '封面图URL' }}"
            >
          </div>
          
          <div class="mb-3">
            <label class="block text-sm text-gray-600 mb-1">自定义样式 (CSS)</label>
            <input 
              type="text" 
              v-model="selectedElement.style.cssText"
              @input="updateElementStyleFromCssText"
              class="w-full p-2 border border-gray-300 rounded text-sm"
              placeholder="width: 50%; margin: 0 auto;"
            >
          </div>
          
          <div class="mb-3">
            <button 
              @click="triggerMediaUpload(selectedElement.id)"
              class="w-full py-2 border border-dashed border-gray-300 rounded text-sm text-gray-600 hover:bg-gray-50 transition-colors"
            >
              <i class="fa fa-upload mr-1"></i> 上传{{ selectedElement.type === 'image' ? '图片' : selectedElement.type === 'video' ? '视频' : '音频' }}
            </button>
            <input 
              type="file" 
              :accept="selectedElement.type === 'image' ? 'image/*' : selectedElement.type === 'video' ? 'video/*' : 'audio/*'" 
              ref="mediaInput"
              class="hidden"
              @change="handleMediaUpload(selectedElement.id, $event)"
            >
          </div>
        </div>
        
        <div v-if="selectedElement.type === 'button'">
          <div class="mb-3">
            <label class="block text-sm text-gray-600 mb-1">按钮内容</label>
            <textarea 
              v-model="selectedElement.content"
              @input="updateElementProperties"
              class="w-full p-2 border border-gray-300 rounded text-sm min-h-[60px]"
            ></textarea>
          </div>
          <div class="mb-3">
            <label class="block text-sm text-gray-600 mb-1">按钮链接</label>
            <input 
              type="text" 
              v-model="selectedElement.link"
              @input="updateElementProperties"
              class="w-full p-2 border border-gray-300 rounded text-sm"
              placeholder="https://example.com"
            >
          </div>
          <div class="mb-3">
            <label class="block text-sm text-gray-600 mb-1">自定义样式 (CSS)</label>
            <input 
              type="text" 
              v-model="selectedElement.style.cssText"
              @input="updateElementStyleFromCssText"
              class="w-full p-2 border border-gray-300 rounded text-sm"
              placeholder="background: blue; color: white; padding: 10px 20px;"
            >
          </div>
        </div>
      </div>
    </main>
    
    <!-- 导入HTML弹窗 -->
    <div v-if="showImportDialog" class="fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4">
      <div class="bg-white rounded-lg w-full max-w-lg max-h-[80vh] overflow-hidden flex flex-col">
        <div class="p-4 border-b border-gray-200 flex justify-between items-center">
          <h3 class="font-medium text-lg">导入HTML</h3>
          <button class="text-gray-500 hover:text-gray-700" @click="showImportDialog = false">
            <i class="fa fa-times"></i>
          </button>
        </div>
        <div class="p-4 overflow-y-auto">
          <div class="mb-4">
            <label class="block text-sm text-gray-600 mb-2">上传HTML文件</label>
            <input 
              type="file" 
              accept=".html,.htm" 
              @change="handleHtmlFileImport($event)"
              class="w-full p-2 border border-gray-300 rounded text-sm"
            >
          </div>
          
          <div class="mb-4">
            <label class="block text-sm text-gray-600 mb-2">或直接粘贴HTML代码</label>
            <textarea 
              v-model="importHtmlContent"
              class="w-full p-2 border border-gray-300 rounded text-sm min-h-[200px]"
              placeholder="粘贴HTML代码..."
            ></textarea>
          </div>
          
          <div class="mb-4">
            <label class="block text-sm text-gray-600 mb-2">导入模式</label>
            <div class="flex space-x-4">
              <label class="inline-flex items-center">
                <input 
                  type="radio" 
                  v-model="importMode" 
                  value="structured" 
                  class="mr-2"
                >
                <span>结构化导入 (可编辑元素)</span>
              </label>
              <label class="inline-flex items-center">
                <input 
                  type="radio" 
                  v-model="importMode" 
                  value="raw" 
                  class="mr-2"
                >
                <span>原始导入 (保留原样)</span>
              </label>
            </div>
          </div>
          
          <div class="text-sm text-gray-500 mb-4">
            <p><i class="fa fa-info-circle mr-1"></i> 结构化导入: 转换为可编辑元素 | 原始导入: 保持完整HTML结构和样式</p>
          </div>
          
          <button 
            @click="processImportedHtml"
            class="w-full py-2 bg-primary text-white rounded text-sm hover:bg-primary/90 transition-colors"
          >
            导入内容
          </button>
        </div>
      </div>
    </div>
    
    <!-- 底部状态栏 -->
    <footer class="bg-dark text-white py-1 px-4 text-xs flex justify-between items-center z-10">
      <div>
        <span class="mr-4">元素数量: {{ contentElements.length }} | 变量数量: {{ variables.length }}</span>
        <span v-if="isSaved">✓ 已保存</span>
        <span v-else class="text-yellow-400">• 未保存</span>
      </div>
      <div>
        <button class="text-gray-300 hover:text-white" @click="showHelp = true">
          <i class="fa fa-question-circle mr-1"></i>帮助
        </button>
      </div>
    </footer>
    
    <!-- 帮助弹窗 -->
    <div v-if="showHelp" class="fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4">
      <div class="bg-white rounded-lg w-full max-w-lg max-h-[80vh] overflow-hidden flex flex-col">
        <div class="p-4 border-b border-gray-200 flex justify-between items-center">
          <h3 class="font-medium text-lg">使用帮助</h3>
          <button class="text-gray-500 hover:text-gray-700" @click="showHelp = false">
            <i class="fa fa-times"></i>
          </button>
        </div>
        <div class="p-4 overflow-y-auto">
          <h4 class="font-medium mb-2">HTML导入功能</h4>
          <ul class="list-disc pl-5 text-sm text-gray-700 space-y-1 mb-4">
            <li>提供两种导入模式: 结构化导入(可编辑)和原始导入(保持原样)</li>
            <li>原始导入会保留所有HTML标签、样式和结构</li>
            <li>结构化导入会转换为编辑器可识别的元素，便于后续编辑</li>
          </ul>
          
          <h4 class="font-medium mb-2">原始HTML块</h4>
          <ul class="list-disc pl-5 text-sm text-gray-700 space-y-1 mb-4">
            <li>可直接添加原始HTML块，保留所有标签和样式</li>
            <li>选中原始HTML块后可编辑其源代码</li>
            <li>适合插入复杂内容或保留特定样式</li>
          </ul>
          
          <h4 class="font-medium mb-2">媒体元素支持</h4>
          <ul class="list-disc pl-5 text-sm text-gray-700 space-y-1 mb-4">
            <li>图片、视频、音频可通过URL直接输入</li>
            <li>也可上传本地文件（会转换为Base64格式）</li>
            <li>所有媒体元素都支持自定义CSS样式</li>
          </ul>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'EnhancedVisualEditor',
  data() {
    return {
      // 编辑器状态
      isEditMode: true,
      showHelp: false,
      isSaved: true,
      selectedElement: null,
      selectedIndex: -1,
      showVariables: false,
      showImportDialog: false,
      importHtmlContent: '',
      importMode: 'raw', // 'structured' 或 'raw'
      
      // 内容元素
      contentElements: [
        {
          id: this.generateId(),
          type: 'heading',
          level: 2,
          content: '欢迎使用增强型可视化编辑器',
          style: { textAlign: 'left' }
        },
        {
          id: this.generateId(),
          type: 'paragraph',
          content: '这个编辑器支持两种HTML导入模式：<br>1. 原始导入 - 完全保持HTML原样和样式<br>2. 结构化导入 - 转换为可编辑元素',
          style: { textAlign: 'left' }
        },
        {
          id: this.generateId(),
          type: 'rawHtml',
          content: '<div style="background: #f0f8ff; padding: 15px; border-left: 4px solid #165DFF;"><h4 style="margin-top: 0; color: #165DFF;">原始HTML块示例</h4><p>这个区块保留了完整的HTML结构和样式</p><ul><li>列表项1</li><li>列表项2</li></ul></div>',
          style: {}
        }
      ],
      
      // 变量列表
      variables: [
        { name: 'site_name', value: '我的网站' },
        { name: 'copyright_year', value: '2023' },
        { name: 'contact_email', value: 'contact@example.com' }
      ],
      
      // 历史记录
      history: [],
      historyIndex: -1,
      historyLimit: 50,
      
      // 媒体编辑临时数据
      mediaEditData: {
        type: '',
        id: '',
        src: '',
        alt: '',
        poster: '',
        style: {}
      },
      
      currentMediaId: null
    }
  },
  methods: {
    // 生成唯一ID
    generateId() {
      return Date.now().toString(36) + Math.random().toString(36).substr(2, 5);
    },
    
    // 变量替换核心函数
    replaceVariables(content) {
      if (!content) return content;
      
      let result = content;
      const variableRegex = /\$\{(\w+)\}/g;
      const matches = content.match(variableRegex);
      
      if (matches) {
        matches.forEach(match => {
          const varName = match.substring(2, match.length - 1);
          const variable = this.variables.find(v => v.name === varName);
          
          if (variable) {
            result = result.replace(match, variable.value);
          } else {
            result = result.replace(match, `<span class="text-red-500 bg-red-50 px-1">${match} <span class="text-xs">(未定义)</span></span>`);
          }
        });
      }
      
      return result;
    },
    
    // 导入HTML相关
    importHtml() {
      this.showImportDialog = true;
      this.importHtmlContent = '';
      this.importMode = 'raw'; // 默认使用原始导入模式
    },
    
    handleHtmlFileImport(event) {
      const file = event.target.files[0];
      if (!file) return;
      
      if (!file.name.endsWith('.html') && !file.name.endsWith('.htm')) {
        this.showNotification('请选择HTML文件', 'error');
        return;
      }
      
      const reader = new FileReader();
      reader.onload = (e) => {
        this.importHtmlContent = e.target.result;
      };
      reader.readAsText(file);
      
      // 重置文件输入
      event.target.value = '';
    },
    
    processImportedHtml() {
      if (!this.importHtmlContent.trim()) {
        this.showNotification('请输入HTML内容', 'error');
        return;
      }
      
      try {
        this.addToHistory();
        
        if (this.importMode === 'raw') {
          // 原始导入模式 - 保持完整HTML结构
          this.contentElements.push({
            id: this.generateId(),
            type: 'rawHtml',
            content: this.importHtmlContent,
            style: {}
          });
          this.showNotification('HTML已按原始格式导入');
        } else {
          // 结构化导入模式 - 转换为可编辑元素
          const tempDiv = document.createElement('div');
          tempDiv.innerHTML = this.importHtmlContent;
          
          const newElements = [];
          
          // 提取head中的样式
          const styleSheets = [];
          const styleElements = tempDiv.querySelectorAll('style');
          styleElements.forEach(style => {
            styleSheets.push(style.innerHTML);
            style.remove(); // 从body中移除style元素
          });
          
          // 如果有样式，添加到内容中
          if (styleSheets.length > 0) {
            newElements.push({
              id: this.generateId(),
              type: 'rawHtml',
              content: `<style>${styleSheets.join('\n')}</style>`,
              style: {}
            });
          }
          
          // 处理body中的元素
          const bodyContent = tempDiv.innerHTML;
          if (bodyContent.trim()) {
            // 尝试提取主要块级元素
            const bodyDiv = document.createElement('div');
            bodyDiv.innerHTML = bodyContent;
            
            const elements = bodyDiv.children;
            for (let i = 0; i < elements.length; i++) {
              const el = elements[i];
              newElements.push({
                id: this.generateId(),
                type: 'rawHtml',
                content: el.outerHTML,
                style: {}
              });
            }
          }
          
          if (newElements.length > 0) {
            this.contentElements = [...this.contentElements, ...newElements];
            this.showNotification(`成功导入 ${newElements.length} 个元素`);
          } else {
            this.showNotification('未找到可导入的元素', 'info');
          }
        }
        
        this.showImportDialog = false;
        this.isSaved = false;
      } catch (e) {
        console.error('HTML导入失败', e);
        this.showNotification('HTML导入失败，请检查格式', 'error');
      }
    },
    
    // 从样式中获取CSS文本
    getStyleCssText(element) {
      if (!element) return '';
      
      const computedStyle = window.getComputedStyle(element);
      const cssProps = [];
      
      for (let i = 0; i < computedStyle.length; i++) {
        const prop = computedStyle[i];
        cssProps.push(`${prop}: ${computedStyle[prop]};`);
      }
      
      return cssProps.join(' ');
    },
    
    // 变量管理
    addNewVariable() {
      this.addToHistory();
      const newVarName = `variable_${this.variables.length + 1}`;
      this.variables.push({
        name: newVarName,
        value: ''
      });
      this.isSaved = false;
    },
    
    removeVariable(index) {
      this.addToHistory();
      this.variables.splice(index, 1);
      this.isSaved = false;
    },
    
    validateVariableName(index) {
      this.addToHistory();
      let varName = this.variables[index].name.trim();
      
      if (!varName) {
        varName = `variable_${Date.now().toString().slice(-4)}`;
        this.variables[index].name = varName;
        this.showNotification('变量名不能为空，已自动生成', 'info');
      }
      
      const isDuplicate = this.variables.some((v, i) => i !== index && v.name === varName);
      if (isDuplicate) {
        const newName = `${varName}_${Date.now().toString().slice(-4)}`;
        this.variables[index].name = newName;
        this.showNotification(`变量名已存在，已自动更改为 ${newName}`, 'info');
      }
      
      this.isSaved = false;
    },
    
    updateVariableValue(index) {
      this.addToHistory();
      this.isSaved = false;
    },
    
    insertVariable(varName) {
      if (!varName || !this.selectedElement || !['heading', 'paragraph', 'button', 'rawHtml'].includes(this.selectedElement.type)) {
        return;
      }
      
      this.addToHistory();
      
      const index = this.contentElements.findIndex(el => el.id === this.selectedElement.id);
      if (index !== -1) {
        const variableTag = `\${${varName}}`;
        this.contentElements[index].content += variableTag;
        this.selectedElement.content = this.contentElements[index].content;
        this.isSaved = false;
      }
    },
    
    // 保存和导出
    saveContent() {
      const saveData = {
        contentElements: this.contentElements,
        variables: this.variables
      };
      localStorage.setItem('enhancedEditorContent', JSON.stringify(saveData));
      this.isSaved = true;
      this.showNotification('内容和变量已保存');
    },
    
    exportHtml() {
      let html = `<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>导出的页面</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      max-width: 800px;
      margin: 0 auto;
      padding: 20px;
      color: #333;
    }
    .container {
      padding: 20px;
    }
    img, video {
      max-width: 100%;
      height: auto;
    }
    audio {
      width: 100%;
      margin: 10px 0;
    }
    button {
      cursor: pointer;
    }
  </style>
</head>
<body>
  <div class="container">`;
      
      this.contentElements.forEach(element => {
        if (element.type === 'rawHtml') {
          // 原始HTML块直接输出
          html += this.replaceVariables(element.content);
        } else {
          // 处理其他元素类型
          switch(element.type) {
            case 'heading':
              const headingContent = this.replaceVariables(element.content);
              html += `<h${element.level} style="${this.getStyleString(element.style)}">${headingContent}</h${element.level}>`;
              break;
            case 'paragraph':
              const paragraphContent = this.replaceVariables(element.content);
              html += `<p style="${this.getStyleString(element.style)}">${paragraphContent}</p>`;
              break;
            case 'image':
              const imageSrc = this.replaceVariables(element.src);
              const imageAlt = this.replaceVariables(element.alt || '');
              html += `<img src="${imageSrc}" alt="${imageAlt}" style="${this.getStyleString(element.style)}">`;
              break;
            case 'video':
              const videoSrc = this.replaceVariables(element.src);
              const videoPoster = this.replaceVariables(element.poster || '');
              html += `<video src="${videoSrc}" ${videoPoster ? `poster="${videoPoster}"` : ''} controls style="${this.getStyleString(element.style)}">您的浏览器不支持视频播放</video>`;
              break;
            case 'audio':
              const audioSrc = this.replaceVariables(element.src);
              html += `<audio src="${audioSrc}" controls style="${this.getStyleString(element.style)}">您的浏览器不支持音频播放</audio>`;
              break;
            case 'button':
              const buttonContent = this.replaceVariables(element.content);
              html += `<a href="${element.link || '#'}"><button style="${this.getStyleString(element.style)}">${buttonContent}</button></a>`;
              break;
            case 'divider':
              html += `<hr style="${this.getStyleString(element.style)}">`;
              break;
          }
        }
      });
      
      html += `
  </div>
</body>
</html>`;
      
      const blob = new Blob([html], { type: 'text/html' });
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = 'page_' + new Date().getTime() + '.html';
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      URL.revokeObjectURL(url);
    },
    
    // 将样式对象转换为CSS字符串
    getStyleString(styleObj) {
      if (!styleObj) return '';
      
      // 如果有cssText属性，直接使用
      if (styleObj.cssText) {
        return styleObj.cssText;
      }
      
      // 否则转换样式对象
      return Object.entries(styleObj)
        .map(([key, value]) => `${this.camelToKebab(key)}: ${value}`)
        .join('; ');
    },
    
    // 驼峰式转连字符式 (用于CSS属性)
    camelToKebab(camelCase) {
      return camelCase.replace(/[A-Z]/g, letter => `-${letter.toLowerCase()}`);
    },
    
    // 编辑模式切换
    toggleEditMode() {
      this.isEditMode = !this.isEditMode;
      this.deselectElement();
    },
    
    // 元素选择和编辑
    selectElement(element, index) {
      if (!this.isEditMode) return;
      // 深拷贝元素，避免直接修改原数据
      this.selectedElement = JSON.parse(JSON.stringify(element));
      this.selectedIndex = index;
    },
    
    deselectElement() {
      this.selectedElement = null;
      this.selectedIndex = -1;
    },
    
    addElement(type) {
      this.addToHistory();
      
      let newElement = {
        id: this.generateId(),
        type: type,
        style: {}
      };
      
      switch(type) {
        case 'heading':
          newElement.level = 2;
          newElement.content = '新标题';
          newElement.style = { textAlign: 'left' };
          break;
        case 'paragraph':
          newElement.content = '新段落内容...';
          newElement.style = { textAlign: 'left' };
          break;
        case 'image':
          newElement.src = 'https://picsum.photos/seed/newimage/800/400';
          newElement.alt = '';
          newElement.style = { maxWidth: '100%', height: 'auto' };
          break;
        case 'video':
          newElement.src = 'https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4';
          newElement.poster = 'https://picsum.photos/seed/videothumb/800/450';
          newElement.style = { maxWidth: '100%', height: 'auto' };
          break;
        case 'audio':
          newElement.src = 'https://sample-videos.com/audio/mp3/crowd-cheering.mp3';
          newElement.style = { width: '100%' };
          break;
        case 'button':
          newElement.content = '点击按钮';
          newElement.link = '#';
          newElement.style = { 
            padding: '8px 16px', 
            backgroundColor: '#165DFF', 
            color: 'white', 
            border: 'none', 
            borderRadius: '4px',
            cursor: 'pointer'
          };
          break;
        case 'divider':
          newElement.style = { border: '1px solid #e5e7eb', margin: '1rem 0' };
          break;
        case 'rawHtml':
          newElement.content = '<div style="padding: 10px; border: 1px solid #ccc;"><p>原始HTML内容</p></div>';
          newElement.style = {};
          break;
      }
      
      this.contentElements.push(newElement);
      this.isSaved = false;
    },
    
    updateElementContent(id, content) {
      this.addToHistory();
      
      const index = this.contentElements.findIndex(el => el.id === id);
      if (index !== -1) {
        this.contentElements[index].content = content;
        this.isSaved = false;
      }
    },
    
    updateElementProperties() {
      this.addToHistory();
      
      const index = this.contentElements.findIndex(el => el.id === this.selectedElement.id);
      if (index !== -1) {
        this.contentElements[index] = JSON.parse(JSON.stringify(this.selectedElement));
        this.isSaved = false;
      }
    },
    
    // 从CSS文本更新样式对象
    updateElementStyleFromCssText() {
      if (!this.selectedElement) return;
      
      try {
        const style = this.selectedElement.style;
        style.cssText = this.selectedElement.style.cssText || '';
        
        // 更新属性
        this.updateElementProperties();
      } catch (e) {
        console.error('解析CSS样式失败', e);
        this.showNotification('CSS样式格式不正确', 'error');
      }
    },
    
    deleteElement() {
      if (!this.selectedElement) return;
      
      this.addToHistory();
      this.contentElements = this.contentElements.filter(el => el.id !== this.selectedElement.id);
      this.deselectElement();
      this.isSaved = false;
    },
    
    moveElement(direction) {
      if (!this.selectedElement || (direction === 'up' && this.selectedIndex === 0) || 
          (direction === 'down' && this.selectedIndex === this.contentElements.length - 1)) {
        return;
      }
      
      this.addToHistory();
      
      const newIndex = direction === 'up' ? this.selectedIndex - 1 : this.selectedIndex + 1;
      const elements = [...this.contentElements];
      const temp = elements[this.selectedIndex];
      elements[this.selectedIndex] = elements[newIndex];
      elements[newIndex] = temp;
      
      this.contentElements = elements;
      this.selectedIndex = newIndex;
      this.isSaved = false;
    },
    
    // 媒体文件处理
    openMediaEditDialog(type, id) {
      const element = this.contentElements.find(el => el.id === id);
      if (element) {
        this.mediaEditData = {
          type,
          id,
          src: element.src,
          alt: element.alt || '',
          poster: element.poster || '',
          style: JSON.parse(JSON.stringify(element.style))
        };
      }
    },
    
    triggerMediaUpload(id) {
      this.$refs.mediaInput.click();
      this.currentMediaId = id;
    },
    
    handleMediaUpload(id, event) {
      const file = event.target.files[0];
      if (!file) return;
      
      this.addToHistory();
      
      // 检查文件类型
      const element = this.contentElements.find(el => el.id === id);
      if (!element) return;
      
      const expectedType = element.type;
      if (!file.type.startsWith(expectedType + '/')) {
        this.showNotification(`请上传${expectedType === 'image' ? '图片' : expectedType === 'video' ? '视频' : '音频'}文件`, 'error');
        return;
      }
      
      // 读取媒体文件并显示预览
      const reader = new FileReader();
      reader.onload = (e) => {
        const index = this.contentElements.findIndex(el => el.id === id);
        if (index !== -1) {
          this.contentElements[index].src = e.target.result;
          if (this.selectedElement && this.selectedElement.id === id) {
            this.selectedElement.src = e.target.result;
          }
          this.isSaved = false;
          this.showNotification(`${expectedType === 'image' ? '图片' : expectedType === 'video' ? '视频' : '音频'}已更新`);
        }
      };
      reader.readAsDataURL(file);
      
      // 重置文件输入
      event.target.value = '';
    },
    
    handleButtonClick() {
      if (this.isEditMode && this.selectedElement) {
        // 在编辑模式下点击按钮不执行跳转
        return false;
      }
      // 预览模式下执行跳转
      if (this.selectedElement && this.selectedElement.link) {
        window.open(this.selectedElement.link, '_blank');
      }
    },
    
    // 历史记录
    addToHistory() {
      const state = JSON.stringify({
        contentElements: this.contentElements,
        variables: this.variables
      });
      
      if (this.historyIndex < this.history.length - 1) {
        this.history = this.history.slice(0, this.historyIndex + 1);
      }
      
      this.history.push(state);
      
      if (this.history.length > this.historyLimit) {
        this.history.shift();
      }
      
      this.historyIndex = this.history.length - 1;
    },
    
    undo() {
      if (this.historyIndex > 0) {
        this.historyIndex--;
        const state = JSON.parse(this.history[this.historyIndex]);
        this.contentElements = state.contentElements;
        this.variables = state.variables;
        this.deselectElement();
        this.isSaved = false;
      } else {
        this.showNotification('已到达历史记录起点', 'info');
      }
    },
    
    redo() {
      if (this.historyIndex < this.history.length - 1) {
        this.historyIndex++;
        const state = JSON.parse(this.history[this.historyIndex]);
        this.contentElements = state.contentElements;
        this.variables = state.variables;
        this.deselectElement();
        this.isSaved = false;
      } else {
        this.showNotification('已到达最新记录', 'info');
      }
    },
    
    // 通知
    showNotification(message, type = 'success') {
      const notification = document.createElement('div');
      notification.className = `fixed bottom-4 right-4 px-4 py-2 rounded shadow-lg ${
        type === 'success' ? 'bg-green-500 text-white' :
        type === 'error' ? 'bg-red-500 text-white' :
        'bg-blue-500 text-white'
      }`;
      notification.textContent = message;
      document.body.appendChild(notification);
      
      setTimeout(() => {
        notification.style.opacity = '0';
        notification.style.transition = 'opacity 0.3s';
        setTimeout(() => {
          document.body.removeChild(notification);
        }, 300);
      }, 3000);
    }
  },
  mounted() {
    // 尝试加载保存的内容
    const savedData = localStorage.getItem('enhancedEditorContent');
    if (savedData) {
      try {
        const { contentElements, variables } = JSON.parse(savedData);
        this.contentElements = contentElements;
        this.variables = variables;
      } catch (e) {
        console.error('加载保存的内容失败', e);
      }
    }
    
    // 初始化历史记录
    this.addToHistory();
  }
}
</script>

<style scoped>
/* 自定义滚动条样式 */
::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}
::-webkit-scrollbar-track {
  background: #f1f1f1;
}
::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}

/* 编辑元素样式 */
[contenteditable=true] {
  outline: 1px dashed #165DFF;
  min-height: 24px;
}

/* 工具栏按钮样式 */
.toolbar-btn {
  @apply p-2 rounded hover:bg-gray-100 transition-colors duration-200;
}
.toolbar-btn.active {
  @apply bg-primary/10 text-primary;
}

/* 媒体元素容器 */
.media-container {
  @apply relative my-4;
}
</style>
    